﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace AudiPyme.DAL
{
    public class EmpresasFactory
    {
        //Método que actualiza los datos de una empresa
        public static bool ActualizaDatosEmpresa(int IdEmpresa, String NombreEmpresa, int IdSector, int IdTipoEmpresa, int NumEmpleados)
        {
            bool actualizado = false;
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<Empresas> EmpAct = from e in agenteBD.EmpresasEstablecer
                                          where e.IdEmpresa == IdEmpresa
                                          select e;
            //Si no se ha podido recoger la empresa se devuelve un false
            if (EmpAct.Count() == 0)
            {
                actualizado = false;
            }
            //Actualizamos los campos de la empresa recogida
            else
            {
                Empresas EmpresaAct = EmpAct.First();
                EmpresaAct.Nombre = NombreEmpresa;
                EmpresaAct.IdSector = IdSector;
                EmpresaAct.IdTipoEmpresa = IdTipoEmpresa;
                EmpresaAct.NumEmpleados = NumEmpleados;
                agenteBD.SaveChanges();
                actualizado = true;
            }
            return actualizado;
        }

        //Devuelve la madurez deseada de una empresa
        public static int MadurezDeseadaEmpresa(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<int> Empresa = from u in agenteBD.EmpresasEstablecer
                                      where u.IdEmpresa == IdEmpresa && u.MadurezDeseada != null
                                      select u.MadurezDeseada.Value;
            if (Empresa.Count() == 0)
            {
                return 0;
            }
            else
            {
                return Empresa.First();
            }
        }

        //Devuelve la media del nivel de madurez deseada de las empresas pertenecientes a un sector y tamaño dados
        public static double MediaMadurezDeseadaTipoSector(int IdSector, int TipoEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int contador = 0;
            double sumatorioPesos = 0.0;
            IQueryable<int?> MadDesEmpresas = from t in agenteBD.EmpresasEstablecer
                                              where t.IdSector == IdSector && t.IdTipoEmpresa == TipoEmpresa
                                                     && t.MadurezDeseada != null
                                              select t.MadurezDeseada;
            if (MadDesEmpresas.Count() == 0)
            {
                return -1.0;
            }
            else
            {
                foreach (double MadDes in MadDesEmpresas)
                {
                    if (MadDesEmpresas.First().HasValue)
                    {
                        contador++;
                        sumatorioPesos = sumatorioPesos + MadDes;
                    }
                }
                double media = ((double)sumatorioPesos / (double)contador);
                return media;
            }
        }

        //Devuelve la media del nivel de madurez actual de las empresas pertenecientes a un sector y tamaño dados
        public static double MediaMadurezActualTipoSector(int IdSector, int TipoEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int contador = 0;
            double sumatorioPesos = 0.0;
            IQueryable<int?> MadDesEmpresas = from t in agenteBD.EmpresasEstablecer
                                              where t.IdSector == IdSector && t.IdTipoEmpresa == TipoEmpresa
                                                     && t.MadurezActual != null
                                              select t.MadurezActual;
            if (MadDesEmpresas.Count() == 0)
            {
                return -1.0;
            }
            else
            {
                foreach (double MadDes in MadDesEmpresas)
                {
                    if (MadDesEmpresas.First().HasValue)
                    {
                        contador++;
                        sumatorioPesos = sumatorioPesos + MadDes;
                    }
                }
                double media = ((double)sumatorioPesos / (double)contador);
                return media;
            }
        }

        //Devuelve el peso de la variable sector-tamaño empresa 
        public static double MadurezDeseadaSecTamEmpresa(int IdEmpresa)
        {
            int IdSectorEmpresa = EmpresasFactory.IdSectorEmpresa(IdEmpresa);
            int TamanioEmpresa = EmpresasFactory.IdTipoEmpresaEmpresa(IdEmpresa);
            int numeroEmpresas = 0;
            int acumuladoMadurezEmpresas = 0;
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<int> MadurezEmpresas = from u in agenteBD.EmpresasEstablecer
                                              where u.IdSector == IdSectorEmpresa &&
                                                    u.IdTipoEmpresa == TamanioEmpresa && u.MadurezDeseada != null
                                              select u.MadurezDeseada.Value;
            foreach (int MadEmp in MadurezEmpresas)
            {
                acumuladoMadurezEmpresas = acumuladoMadurezEmpresas + MadEmp;
                numeroEmpresas++;
            }
            //Para evitar la indeterminacion 0/0
            if (numeroEmpresas != 0)
            {
                double MadurezDeseadaMedia = (double)acumuladoMadurezEmpresas / (double)numeroEmpresas;
                return MadurezDeseadaMedia;
            }
            //Indeterminación 0/0. Devuelve 0.0
            else
            {
                return 0.0;
            }
        }

        //Devuelve la madurez actual de una empresa
        public static int MadurezActualEmpresa(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<int> Empresa = from u in agenteBD.EmpresasEstablecer
                                      where u.IdEmpresa == IdEmpresa && u.MadurezActual != null
                                      select u.MadurezActual.Value;
            if (Empresa.Count() == 0)
            {
                return 0;
            }
            else
            {
                return Empresa.First();
            }
        }

        //Madurez Actual de una Empresa en un Informe dado
        public static int MadurezActualEmpresaInforme(int IdInforme)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<int> Empresa = from EmpInf in agenteBD.EmpresaInformeEstablecer
                                      where EmpInf.IdInforme == IdInforme
                                      select EmpInf.MadurezActualInf;
            if (Empresa.Count() == 0)
            {
                return 0;
            }
            else
            {
                return Empresa.First();
            }
        }

        //Pesos medios de la madurez según las empresas homónimas a IdEmpresa
        public static double MadurezActualSecTamEmpresa(int IdEmpresa)
        {
            int IdSectorEmpresa = EmpresasFactory.IdSectorEmpresa(IdEmpresa);
            int TamanioEmpresa = EmpresasFactory.IdTipoEmpresaEmpresa(IdEmpresa);
            int numeroEmpresas = 0;
            int acumuladoMadurezEmpresas = 0;
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<int> MadurezEmpresas = from u in agenteBD.EmpresasEstablecer
                                              where u.IdSector == IdSectorEmpresa &&
                                                    u.IdTipoEmpresa == TamanioEmpresa && u.MadurezActual != null
                                              select u.MadurezActual.Value;
            foreach (int MadEmp in MadurezEmpresas)
            {
                acumuladoMadurezEmpresas = acumuladoMadurezEmpresas + MadEmp;
                numeroEmpresas++;
            }
            double MadurezActualMedia = (double)acumuladoMadurezEmpresas / (double)numeroEmpresas;
            return MadurezActualMedia;
        }

        //Método para sacar el Nivel de Madurez de una Empresa por los Controles parametrizados por su nivel de Madurez
        //El valor varía de 0 a 1
        public static double ControlesNivMadurezEmpresa(int IdEmpresa, int NivelMadurez)
        {
            //Sacamos los controles por nivel de madurez
            double ContrNivMadurez = -1.0;
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<String> RespContr = from CE in agenteBD.ControlesEmpresaEstablecer
                                           join C in agenteBD.ControlesEstablecer on CE.IdControl equals C.IdControl
                                           where C.NivelMadurez == NivelMadurez && CE.IdEmpresa == IdEmpresa
                                           select CE.Valor;
            int numeroControles = 0;
            double sumatorio = 0.0;
            int numControlesNA = 0;
            foreach (String Resp in RespContr)
            {
                String Respuesta = Resp.Trim();
                numeroControles++;
                switch (Respuesta)
                {
                    case "SI":
                        sumatorio = sumatorio + 1;
                        break;
                    case "PARC":
                        sumatorio = sumatorio + 0.5;
                        break;
                    case "N/A":
                        numControlesNA++;
                        break;
                }
            }
            ContrNivMadurez = sumatorio / (numeroControles - numControlesNA);
            return ContrNivMadurez;
        }

        //Cobertura de los controles asociados a las empresas con un sector y tamaño dados según el nivel de madurez de estos
        public static double ControlesNivMadurezSectTipEmp(int IdSector, int IdTipoEmpresa, int NivelMadurez)
        {
            //Sacamos los controles por nivel de madurez
            double ContrNivMadurez = -1.0;
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<String> RespContr = from CE in agenteBD.ControlesEmpresaEstablecer
                                           join C in agenteBD.ControlesEstablecer on CE.IdControl equals C.IdControl
                                           join E in agenteBD.EmpresasEstablecer on CE.IdEmpresa equals E.IdEmpresa
                                           where E.IdSector == IdSector && E.IdTipoEmpresa == IdTipoEmpresa
                                                 && C.NivelMadurez == NivelMadurez
                                           select CE.Valor;
            int numeroControles = 0;
            double sumatorio = 0.0;
            int numControlesNA = 0;
            foreach (String Resp in RespContr)
            {
                String Respuesta = Resp.Trim();
                numeroControles++;
                switch (Respuesta)
                {
                    case "SI":
                        sumatorio = sumatorio + 1;
                        break;
                    case "PARC":
                        sumatorio = sumatorio + 0.5;
                        break;
                    case "N/A":
                        numControlesNA++;
                        break;
                }
            }
            ContrNivMadurez = sumatorio / (numeroControles - numControlesNA);
            return ContrNivMadurez;

        }

        //Devuelve el nombre de la empresa según su identificador
        public static String NombreEmpresa(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<string> Empresa = from e in agenteBD.EmpresasEstablecer
                                         where e.IdEmpresa == IdEmpresa && e.Nombre != null
                                         select e.Nombre;
            if (Empresa.Count() == 0)
            {
                return "";
            }
            else
            {
                return Empresa.First();
            }
        }

        //Devuelve una cadena con el número de empleados de una empresa
        public static String NumeroEmpleados(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<int> NumEmpleados = from e in agenteBD.EmpresasEstablecer
                                           where e.IdEmpresa == IdEmpresa && e.NumEmpleados != null
                                           select e.NumEmpleados;
            if (NumEmpleados.Count() == 0)
            {
                return "No se han establecido";
            }
            else
            {
                return NumEmpleados.First().ToString();
            }
        }

        //Devuelve el identificador del sector de una empresa
        public static int IdSectorEmpresa(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<int> IdSector = from e in agenteBD.EmpresasEstablecer
                                       where e.IdEmpresa == IdEmpresa && e.Nombre != null
                                       select e.IdSector;
            if (IdSector.Count() == 0)
            {
                return 0;
            }
            else
            {
                return IdSector.First();
            }
        }

        //Devuelve el nombre del sector de una empresa
        public static String SectorEmpresa(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<int> IdSector = from e in agenteBD.EmpresasEstablecer
                                       where e.IdEmpresa == IdEmpresa && e.Nombre != null
                                       select e.IdSector;
            if (IdSector.Count() == 0)
            {
                return "";
            }
            else
            {
                int IdSectorEncontrado = IdSector.First();
                IQueryable<String> NombreSector = from s in agenteBD.SectoresEstablecer
                                                  where s.IdSector == IdSectorEncontrado && s.NombreSector != null
                                                  select s.NombreSector;
                if (IdSector.Count() == 0)
                {
                    return "";
                }
                else
                {
                    return NombreSector.First();
                }
            }
        }
    
        //Devuelve el identificador de Tipo de Empresa asociado a una empresa
        public static int IdTipoEmpresaEmpresa(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<int> IdTipoEmpresa = from t in agenteBD.EmpresasEstablecer
                                            where t.IdEmpresa == IdEmpresa && t.Nombre != null
                                            select t.IdTipoEmpresa;
            if (IdTipoEmpresa.Count() == 0)
            {
                return 0;
            }
            else
            {
                return IdTipoEmpresa.First();
            }
        }

        //Devuelve el nombre del tipo de empresa asociado a una empresa
        public static String TipoEmpresaEmpresa(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<int> IdTipoEmpresa = from t in agenteBD.EmpresasEstablecer
                                            where t.IdEmpresa == IdEmpresa && t.Nombre != null
                                            select t.IdTipoEmpresa;
            if (IdTipoEmpresa.Count() == 0)
            {
                return "";
            }
            else
            {
                int IdTipoEmpresaEncontrado = IdTipoEmpresa.First();
                IQueryable<String> NombreTipoEmpresa = from e in agenteBD.TipoEmpresaEstablecer
                                                       where e.IdTipoEmpresa == IdTipoEmpresaEncontrado && e.NombreTipoEmpresa != null
                                                       select e.NombreTipoEmpresa;
                if (NombreTipoEmpresa.Count() == 0)
                {
                    return "";
                }
                else
                {
                    return NombreTipoEmpresa.First();
                }
            }
        }

        //Devuelve la facturación de una empresa
        public static int FacturacionEmpresa(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<int?> FacturEmpresa = from t in agenteBD.EmpresasEstablecer
                                             where t.IdEmpresa == IdEmpresa && t.Facturacion != null
                                             select t.Facturacion;
            if (FacturEmpresa.Count() == 0)
            {
                return 0;
            }
            else
            {
                if (!FacturEmpresa.First().HasValue)
                {
                    return 0;
                }
                else
                {
                    int Facturacion = FacturEmpresa.First().Value;
                    return Facturacion;
                }
            }
        }

        //Calcula el Nivel de Madurez Deseada de una empresa a través de los pesos sector y facturación y las respuestas a las preguntas TIC
        public static int CalcularNivelMadurezDeseadaEmpresa(double PesoSectorTipoEmpresa, double PesoCifraNegocio, List<double> PesosPreguntasTIC, int IdEmpresa)
        {
            int NivelMadurezActualEmpresa = 0;
            double PesoMedioNivelMadurezEmpresa = 0.0;
            double PesosTotalesPreguntasTIC = 0.0;
            for (int i = 0; i < PesosPreguntasTIC.Capacity; i++)
            {
                PesosTotalesPreguntasTIC += PesosPreguntasTIC[i];
            }
            double PesoPreguntasTIC = PesosTotalesPreguntasTIC;
            //Insertamos los pesos calculados en la empresa
            InsertarPesoSector(PesoSectorTipoEmpresa, IdEmpresa);
            InsertarPesoNegocio(PesoCifraNegocio, IdEmpresa);
            InsertarPesoTIC(PesoPreguntasTIC, IdEmpresa);
            //Calculamos el Nivel de Madurez Deseable
            PesoMedioNivelMadurezEmpresa = (PesoPreguntasTIC + PesoSectorTipoEmpresa + PesoCifraNegocio) / 3.0;
            if (PesoMedioNivelMadurezEmpresa < 0.25)
            {
                NivelMadurezActualEmpresa = 1;
            }
            else if (PesoMedioNivelMadurezEmpresa >= 0.25 && PesoMedioNivelMadurezEmpresa < 0.75)
            {
                NivelMadurezActualEmpresa = 2;
            }
            // 1>PesoMedioNivelMadurezEmpresa>=0.75
            else
            {
                NivelMadurezActualEmpresa = 3;
            }
            return NivelMadurezActualEmpresa;
        }

        //Calcula el Nivel de Madurez Deseada de una empresa a través de los pesos sector, facturación y TIC
        public static int CalcularNivelMadurezDeseadaEmpresa(double PesoSectorTipoEmpresa, double PesoCifraNegocio, double PesoTIC, int IdEmpresa)
        {
            int NivelMadurezActualEmpresa = 0;
            //Calculamos el Nivel de Madurez Deseable
            double PesoMedioNivelMadurezEmpresa = (PesoTIC + PesoSectorTipoEmpresa + PesoCifraNegocio) / 3.0;
            if (PesoMedioNivelMadurezEmpresa < 0.25)
            {
                NivelMadurezActualEmpresa = 1;
            }
            else if (PesoMedioNivelMadurezEmpresa >= 0.25 && PesoMedioNivelMadurezEmpresa < 0.75)
            {
                NivelMadurezActualEmpresa = 2;
            }
            // 1>PesoMedioNivelMadurezEmpresa>=0.75
            else
            {
                NivelMadurezActualEmpresa = 3;
            }
            return NivelMadurezActualEmpresa;
        }

        //Inserta el peso del parámetro sector del nivel de madurez deseable de una empresa
        public static void InsertarPesoSector(double PesoSector, int IdEmpresa)
        {
            double PesoSectorIns = Math.Round(PesoSector, 3);
            ModeloContainer agenteBD = new ModeloContainer();
            var Empresa = (from p in agenteBD.EmpresasEstablecer
                           where p.IdEmpresa == IdEmpresa
                           select p).Single();
            Empresa.PesoSector = PesoSectorIns;
            agenteBD.SaveChanges();
        }

        //Calcula el parámetro sector del nivel de madurez deseable de una empresa
        public static double PesoSectorEmpresa(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<double?> PesSector = from t in agenteBD.EmpresasEstablecer
                                            where t.IdEmpresa == IdEmpresa && t.PesoSector != null
                                            select t.PesoSector;
            if (PesSector.Count() == 0)
            {
                return -1.0;
            }
            else
            {
                if (!PesSector.First().HasValue)
                {
                    return -1.0;
                }
                else
                {
                    double PesoSectorEmp = PesSector.First().Value;
                    return PesoSectorEmp;
                }
            }
        }

        //Media de los pesos sector correspondientes a las empresas de un sector y tamaño dados
        public static double MediaPesoSectorTipoSector(int IdSector, int TipoEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int contador = 0;
            double sumatorioPesos = 0.0;
            IQueryable<double?> PesosEmpresas = from t in agenteBD.EmpresasEstablecer
                                                where t.IdSector == IdSector && t.IdTipoEmpresa == TipoEmpresa
                                                        && t.PesoSector != null
                                                select t.PesoSector;
            if (PesosEmpresas.Count() == 0)
            {
                return -1.0;
            }
            else
            {
                foreach (double Peso in PesosEmpresas)
                {
                    if (PesosEmpresas.First().HasValue)
                    {
                        contador++;
                        sumatorioPesos = sumatorioPesos + Peso;
                    }
                }
                double media = (sumatorioPesos / contador);
                return media;
            }
        }

        //Inserta el peso del parámetro facturación (negocio) del nivel de madurez deseable de una empresa
        public static void InsertarPesoNegocio(double PesoNegocio, int IdEmpresa)
        {
            double PesoNegocioIns = Math.Round(PesoNegocio, 3);
            ModeloContainer agenteBD = new ModeloContainer();
            var Empresa = (from p in agenteBD.EmpresasEstablecer
                           where p.IdEmpresa == IdEmpresa
                           select p).Single();
            Empresa.PesoNegocio = PesoNegocioIns;
            agenteBD.SaveChanges();
        }

        //Calcula el parámetro facturación (negocio) del nivel de madurez deseable de una empresa
        public static double PesoNegocioEmpresa(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<double?> PesNegoc = from t in agenteBD.EmpresasEstablecer
                                           where t.IdEmpresa == IdEmpresa && t.PesoNegocio != null
                                           select t.PesoNegocio;
            if (PesNegoc.Count() == 0)
            {
                return -1.0;
            }
            else
            {
                if (!PesNegoc.First().HasValue)
                {
                    return -1.0;
                }
                else
                {
                    double PesoNegocioEmp = PesNegoc.First().Value;
                    return PesoNegocioEmp;
                }
            }
        }

        //Media para el peso de facturación (negocio) de todas las empresas pertenecientes a un sector y tamaño dados
        public static double MediaPesoNegocioTipoSector(int IdSector, int TipoEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int contador = 0;
            double sumatorioPesos = 0.0;
            IQueryable<double?> PesosEmpresas = from t in agenteBD.EmpresasEstablecer
                                                where t.IdSector == IdSector && t.IdTipoEmpresa == TipoEmpresa
                                                        && t.PesoNegocio != null
                                                select t.PesoNegocio;
            if (PesosEmpresas.Count() == 0)
            {
                return -1.0;
            }
            else
            {
                foreach (double Peso in PesosEmpresas)
                {
                    if (PesosEmpresas.First().HasValue)
                    {
                        contador++;
                        sumatorioPesos = sumatorioPesos + Peso;
                    }
                }
                double media = (sumatorioPesos / contador);
                return media;
            }
        }

        //Inserta el peso del parámetro asociado a las TIC del nivel de madurez deseable de una empresa
        public static void InsertarPesoTIC(double PesoTIC, int IdEmpresa)
        {
            double PesoTICIns = Math.Round(PesoTIC, 3);
            ModeloContainer agenteBD = new ModeloContainer();
            var Empresa = (from p in agenteBD.EmpresasEstablecer
                           where p.IdEmpresa == IdEmpresa
                           select p).Single();
            Empresa.PesoTIC = PesoTICIns;
            agenteBD.SaveChanges();
        }

        //Calcula el peso de la variable TIC del nivel de madurez deseable para una empresa
        public static double PesoTICEmpresa(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<double?> PesTIC = from t in agenteBD.EmpresasEstablecer
                                         where t.IdEmpresa == IdEmpresa && t.PesoTIC != null
                                         select t.PesoTIC;
            if (PesTIC.Count() == 0)
            {
                return -1.0;
            }
            else
            {
                if (!PesTIC.First().HasValue)
                {
                    return -1.0;
                }
                else
                {
                    double PesoTIC = PesTIC.First().Value;
                    return PesoTIC;
                }
            }
        }

        //Media para el parámetro TIC del nivel de madurez de las empresas pertenecientes a un sector y tamaño dados
        public static double MediaPesoTICTipoSector(int IdSector, int TipoEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int contador = 0;
            double sumatorioPesos = 0.0;
            IQueryable<double?> PesosEmpresas = from t in agenteBD.EmpresasEstablecer
                                                where t.IdSector == IdSector && t.IdTipoEmpresa == TipoEmpresa
                                                        && t.PesoTIC != null
                                                select t.PesoTIC;
            if (PesosEmpresas.Count() == 0)
            {
                return -1.0;
            }
            else
            {
                foreach (double Peso in PesosEmpresas)
                {
                    if (PesosEmpresas.First().HasValue)
                    {
                        contador++;
                        sumatorioPesos = sumatorioPesos + Peso;
                    }
                }
                double media = (sumatorioPesos / contador);
                return media;
            }
        }

        //Calcula la Media entre los tres Pesos, tanto para Empresa como para Sector
        public static double MediaPesos(double PesoSector, double PesoNegocio, double PesoTIC)
        {
            double suma = PesoSector + PesoNegocio + PesoTIC;
            double media = suma / 3;
            return media;
        }

        //Inserta el nivel de madurez deseado para una empresa
        public static void InsertarNivelMadurezDeseado(int IdEmpresa, int NivelMadurez)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            var Empresa = (from e in agenteBD.EmpresasEstablecer
                           where e.IdEmpresa == IdEmpresa
                           select e).Single();
            Empresa.MadurezDeseada = NivelMadurez;
            agenteBD.SaveChanges();
        }

        //Inserta la cifra de negocio de una empresa 
        public static void InsertarCifraNegocioEmpresa(int IdEmpresa, int CifraNegocio)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            var Empresa = (from e in agenteBD.EmpresasEstablecer
                           where e.IdEmpresa == IdEmpresa
                           select e).Single();
            Empresa.Facturacion = CifraNegocio;
            agenteBD.SaveChanges();
        }

        //Inserta el número de asalariados de una empresa
        public static void InsertarNumeroAsalariados(int IdEmpresa, int NumEmpleados)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            var Empresa = (from e in agenteBD.EmpresasEstablecer
                           where e.IdEmpresa == IdEmpresa
                           select e).Single();
            Empresa.NumEmpleados = NumEmpleados;
            agenteBD.SaveChanges();
        }

        //Devuelve una empresa a través de su identificador
        public static Empresas BuscaEmpresa(int IdEmpresa)
        {
            Empresas Empr = new Empresas();
            //Recogemos los Id's asociados al Tipo de Activo, Amenaza y Vulnerabilidad seleccionadas
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<Empresas> Empresa = from Emp in agenteBD.EmpresasEstablecer
                                           where Emp.IdEmpresa == IdEmpresa
                                           select Emp;
            if (Empresa.Count() == 0)
            {
                return null;
            }
            else
            {
                return Empresa.First();
            }
        }

        //Método que elimina una empresa y todos los datos asociados a ella
        public static void EliminarEmpresa(Empresas Empresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<Empresas> EmpresaEliminar = from Empr in agenteBD.EmpresasEstablecer
                                                   where Empr.IdEmpresa == Empresa.IdEmpresa
                                                   select Empr;
            //Recogemos su Id de Empresa
            if (EmpresaEliminar.Count() != 0)
            {
                int IdEmpresa = EmpresaEliminar.First().IdEmpresa;
                //Vamos de las tablas exteriores a las interiores en términos de dependencia con el IdEmpresa
                //PARTE DE INFORMES
                //PlanMejora
                PlanMejoraFactory.EliminaTotalPlanMejora(IdEmpresa);
                //Análisis de Riesgo
                AnalisisRiesgoFactory.EliminaTotalAnalisisRiesgo(IdEmpresa);
                //InstanciasTipoActivoAmenazaCriterioRiesgoInforme
                InstanciaTipactAmenCritriesgInformeFactory.EliminaTotalInstanciasTipAmenCrit(IdEmpresa);
                //InstanciasTipoActivoVulnerabilidadInforme
                InstanciaTipactVulnInformeFactory.EliminaTotalInstanciasTipVuln(IdEmpresa);
                //ControlesInforme
                ControlesEmpresaInformeFactory.EliminaTotalControlesInforme(IdEmpresa);
                //ActivosInforme
                ActivosInformeFactory.EliminaTotalActivosInforme(IdEmpresa);
                //EmpresaInformes, se recoge los Ids de Informes asociados a una empresa
                List<int> LIdsInformes = EmpresaInformeFactory.EliminaTotalEmpresaInforme(IdEmpresa);
                //Informes
                //Para cada Id de Informe recogido se elimina la tupla de Informes con ese Id asociado
                for (int i = 0; i < LIdsInformes.Count(); i++)
                {
                    InformesFactory.EliminaTotalInforme(LIdsInformes[i]);
                }
                //PARTE DE EMPRESA
                //Instancias Tipo Activo - Amenaza - Criterio Riesgo
                InstanciaTiposActivosAmenazasCriteriosRiesgoFactory.EliminaTotalInstanciasTipAmenCrit(IdEmpresa);
                //Instancias Tipo Activo - Vulnerabilidad
                InstanciaTiposActivosVulnerabilidadesFactory.EliminaTotalInstanciasTipVuln(IdEmpresa);
                //ControlesEmpresa
                ControlesEmpresaFactory.EliminaTotalControles(IdEmpresa);
                //ActivosEmpresa
                ActivosEmpresaFactory.EliminaTotalActivos(IdEmpresa);
                //UsuariosEmpresa. Ponemos los usuarios asociados a la empresa a null
                UsuariosFactory.EliminarEmpresaUsuario(IdEmpresa);
                agenteBD.EmpresasEstablecer.DeleteObject(EmpresaEliminar.First());
                agenteBD.SaveChanges();
            }
        }

        //Número de controles que hay en cada nivel de madurez
        public static List<int> NumeroControlesTotalesNiveles()
        {
            //Recogemos el número de controles con Nivel de Madurez 1
            List<int> NumeroControlesNiveles = new List<int>(3);
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<Controles> ControlesNiv1 = from Contr in agenteBD.ControlesEstablecer
                                                  where Contr.NivelMadurez == 1
                                                  select Contr;
            //Si no ha encontrado ningún control es porque ha habido un error. Devolvemos un valor centinela
            if (ControlesNiv1.Count() == 0)
            {
                NumeroControlesNiveles.Insert(0, -1);
            }
            else
            {
                NumeroControlesNiveles.Insert(0, ControlesNiv1.Count());
            }
            //Recogemos el número de controles con Nivel de Madurez 2
            IQueryable<Controles> ControlesNiv2 = from Contr in agenteBD.ControlesEstablecer
                                                  where Contr.NivelMadurez == 2
                                                  select Contr;
            //Si no ha encontrado ningún control es porque ha habido un error. Devolvemos un valor centinela
            if (ControlesNiv2.Count() == 0)
            {
                NumeroControlesNiveles.Insert(1, -1);
            }
            else
            {
                NumeroControlesNiveles.Insert(1, ControlesNiv2.Count());
            }
            //Recogemos el número de controles con Nivel de Madurez 3
            IQueryable<Controles> ControlesNiv3 = from Contr in agenteBD.ControlesEstablecer
                                                  where Contr.NivelMadurez == 3
                                                  select Contr;
            //Si no ha encontrado ningún control es porque ha habido un error. Devolvemos un valor centinela
            if (ControlesNiv3.Count() == 0)
            {
                NumeroControlesNiveles.Insert(2, -1);
            }
            else
            {
                NumeroControlesNiveles.Insert(2, ControlesNiv3.Count());
            }
            return NumeroControlesNiveles;
        }

        //Inserta el nivel de madurez actual de una empresa
        public static void InsertarNivelMadurezActual(int IdEmpresa, int NivelMadurezActual)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            var Empresa = (from e in agenteBD.EmpresasEstablecer
                           where e.IdEmpresa == IdEmpresa
                           select e).Single();
            Empresa.MadurezActual = NivelMadurezActual;
            agenteBD.SaveChanges();
        }

        //Calcula una interpolación para una empresa
        public static double InterpolacionLineal(double x, double xa, double xb, double ya, double yb)
        {
            //Si no se puedieron recoger todos los valores (alguno de ellos tendrá el valor centinela '-1.0'), 
            //se devuelve un valor centinela
            if (x == -1.0 || xa == -1.0 || xb < -1.0 || ya < -1.0 || yb < -1.0)
            {
                return -1.0;
            }
            /* Fórmula de la Interpolación Lineal en Dos Puntos
             * 
             *                        (yb - ya)
             *     y = ya + (x - xa)  ---------
                                      (xb - xa)
             * 
             * */
            double y = (ya + ((x - xa) * ((yb - ya) / (xb - xa))));
            return y;
        }

        //Inserta los valores de las respuestas TIC de una empresa
        public static void InsertarRespuestasTIC(int IdEmpresa, char[] RespuestasTIC)
        {
            String RespTIC = "";
            for (int i = 0; i < RespuestasTIC.Count(); i++)
            {
                RespTIC = RespTIC + RespuestasTIC[i];
            }
            if (RespTIC.Count() != 0)
            {
                ModeloContainer agenteBD = new ModeloContainer();
                var Empresa = (from e in agenteBD.EmpresasEstablecer
                               where e.IdEmpresa == IdEmpresa
                               select e).Single();
                Empresa.RespuestasTIC = RespTIC;
                agenteBD.SaveChanges();
            }
        }

        //Devuelve las respuestas a las preguntas TIC de una empresa
        public static String RecogeRespuestasTIC(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<string> RespuestasTICEmp = from t in agenteBD.EmpresasEstablecer
                                                  where t.IdEmpresa == IdEmpresa
                                                    && t.RespuestasTIC != null
                                                  select t.RespuestasTIC;
            if (RespuestasTICEmp.Count() != 0)
            {
                return RespuestasTICEmp.First();
            }
            else
            {
                //Valor centinela
                return "";
            }

        }

        //Recoge una cadena con el nivel de madurez actual de una empresa
        public static String NMadurezActualEmpresa(int IdEmpresa)
        {
            String NMadurezAct = "";
            int IdMadActual = EmpresasFactory.MadurezActualEmpresa(IdEmpresa);
            switch (IdMadActual)
            {
                case 1:
                    NMadurezAct = "Baja";
                    break;
                case 2:
                    NMadurezAct = "Media";
                    break;
                case 3:
                    NMadurezAct = "Alta";
                    break;
                default:
                    NMadurezAct = "No se ha establecido";
                    break;
            }
            return NMadurezAct;
        }

        //Recoge una cadena con el nivel de madurez deseada de una empresa
        public static String NMadurezDeseadaEmpresa(int IdEmpresa)
        {
            String NMadurezDes = "";
            int IdMadActual = EmpresasFactory.MadurezDeseadaEmpresa(IdEmpresa);
            switch (IdMadActual)
            {
                case 1:
                    NMadurezDes = "Baja";
                    break;
                case 2:
                    NMadurezDes = "Media";
                    break;
                case 3:
                    NMadurezDes = "Alta";
                    break;
                default:
                    NMadurezDes = "No se ha establecido";
                    break;
            }
            return NMadurezDes;
        }

        //Método que calcula el nivel de cumplimiento de los controles segun su nivel de madurez
        public static double CumplimientoNivelMadurez(int[] RespuestaControles)
        {
            //[0]= SI, [1]=NO [2]=PARC [3]=NO APLICA [4]=TOTALES
            double Cobertura = (RespuestaControles[0] + (RespuestaControles[2] * 0.5)) / (RespuestaControles[4] - RespuestaControles[3]);
            //Como es un porcentaje, y lo que devuelve es una variable normalizada [0,1] se multiplica por 100

            return (Math.Round(Cobertura, 4) * 100);

        }

        //Método que revisa si una empresa tiene todos los datos antes de generar el informe
        public static string EmpresaTodosDatosInforme(int IdEmpresa)
        {
            String validador = "";
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<Empresas> EmpresaQuery = from Emp in agenteBD.EmpresasEstablecer
                                                where Emp.IdEmpresa == IdEmpresa
                                                select Emp;
            if (EmpresaQuery.Count() == 0)
            {
                return "*- No hay Empresa asociada al usuario.";
            }
            else
            {
                //Sacamos la Empresa
                Empresas Empresa = EmpresaQuery.First();
                if (!Empresa.Facturacion.HasValue)
                    validador = validador + "\n*-Facturacion ";
                if (!Empresa.MadurezActual.HasValue)
                    validador = validador + "\n*-Madurez Actual ";
                if (!Empresa.MadurezDeseada.HasValue)
                    validador = validador + "\n*-Madurez Deseada ";
                if (!Empresa.PesoSector.HasValue)
                    validador = validador + "\n*-Peso Sector ";
                if (!Empresa.PesoNegocio.HasValue)
                    validador = validador + "\n*- Peso Negocio ";
                if (!Empresa.PesoTIC.HasValue)
                    validador = validador + "\n*- Peso TIC ";
                int numeroActivos = ActivosEmpresaFactory.NumeroTotalesActivosEmpresa(IdEmpresa);
                if (numeroActivos == 0)
                    validador = validador + "\n*- Activos ";
                int numeroRelacTipAct = InstanciaTiposActivosAmenazasCriteriosRiesgoFactory.NumeroTotalRelaciones(IdEmpresa);
                int numeroRelacTipVul = InstanciaTiposActivosVulnerabilidadesFactory.NumeroTotalRelaciones(IdEmpresa);
                if (numeroRelacTipAct == 0 && numeroRelacTipVul == 0)
                    validador = validador + "\n*-Relaciones para los Activos";
                return validador;

            }
        }

        //Método para crear una empresa en la BD a partir de los datos de la misma
        public static int CreaEmpresa(String Nombre, int IdSector, int IdTipoEmpresa, int NumEmpleados)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            Empresas emp = new Empresas();
            emp.Nombre = Nombre;
            emp.IdSector = IdSector;
            emp.IdTipoEmpresa = IdTipoEmpresa;
            emp.NumEmpleados = NumEmpleados;
            agenteBD.AddToEmpresasEstablecer(emp);
            agenteBD.SaveChanges();
            int IdEmpresa = emp.IdEmpresa;
            return IdEmpresa;
        }
    }
}
